package com.github.wxiaoqi.security.crm.core.biz;

import java.math.BigDecimal;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.github.wxiaoqi.security.crm.core.entity.Customer;
import com.github.wxiaoqi.security.crm.core.entity.FreezeJournal;
import com.github.wxiaoqi.security.crm.core.entity.MerchantAccount;
import com.github.wxiaoqi.security.crm.core.entity.MerchantAccountInfo;
import com.github.wxiaoqi.security.crm.core.entity.MerchantAccountJournal;
import com.github.wxiaoqi.security.crm.core.entity.MerchantBase;
import com.github.wxiaoqi.security.crm.core.entity.MerchantBaseExt;
import com.github.wxiaoqi.security.crm.core.entity.PersonalAccount;
import com.github.wxiaoqi.security.crm.core.entity.PersonalAccountJournal;
import com.github.wxiaoqi.security.crm.core.entity.PersonalBase;
import com.github.wxiaoqi.security.crm.core.entity.PersonalBilling;
import com.github.wxiaoqi.security.crm.core.entity.UnfreezeJournal;
import com.github.wxiaoqi.security.crm.core.mapper.CustomerMapper;
import com.github.wxiaoqi.security.crm.core.mapper.FreezeJournalMapper;
import com.github.wxiaoqi.security.crm.core.mapper.MerchantAccountJournalExtMapper;
import com.github.wxiaoqi.security.crm.core.mapper.MerchantAccountJournalMapper;
import com.github.wxiaoqi.security.crm.core.mapper.MerchantAccountMapper;
import com.github.wxiaoqi.security.crm.core.mapper.MerchantBaseExtMapper;
import com.github.wxiaoqi.security.crm.core.mapper.MerchantBaseMapper;
import com.github.wxiaoqi.security.crm.core.mapper.PersonalAccountJournalMapper;
import com.github.wxiaoqi.security.crm.core.mapper.PersonalAccountMapper;
import com.github.wxiaoqi.security.crm.core.mapper.PersonalBaseMapper;
import com.github.wxiaoqi.security.crm.core.mapper.PersonalBillingMapper;
import com.github.wxiaoqi.security.crm.core.mapper.UnfreezeJournalMapper;
import com.github.wxiaoqi.security.auth.common.util.SnowFlake;
import com.github.wxiaoqi.security.common.biz.BaseBiz;
import com.github.wxiaoqi.security.common.msg.AccountType;
import com.github.wxiaoqi.security.common.msg.CustomerType;
import com.github.wxiaoqi.security.common.msg.ResponseCode;
import com.github.wxiaoqi.security.common.util.EntityUtils;
import com.github.wxiaoqi.security.common.util.MD5;
import com.github.wxiaoqi.security.common.vo.RewardRecord;
import lombok.extern.slf4j.Slf4j;

/**
 * 企业账户(冻结账户准入不准出)
 * @author centerroot
 * @email lfw6699@163.com
 * @date 2018-05-25 15:20:48
 */
@Slf4j
@Transactional(rollbackFor = Exception.class)
@Service
public class MerchantAccountBiz extends BaseBiz<MerchantAccountMapper,MerchantAccount> {

	@Autowired
	private PlatformAccoutConfigBiz platformAccoutConfigBiz;
    @Autowired
    private RedisTemplate redisTemplate;
	@Autowired
	private CustomerMapper customerMapper;
	@Autowired
	private PersonalBaseMapper personalBaseMapper;
	@Autowired
	private PersonalAccountBiz personalAccountBiz;
	@Autowired
	private PersonalAccountMapper personalAccountMapper;
	@Autowired
	private PersonalAccountJournalMapper personalAccountJournalMapper;
	@Autowired
	private PersonalBillingMapper personalBillingMapper;
	@Autowired
	private MerchantBaseMapper merchantBaseMapper;
	@Autowired
	private MerchantBaseExtMapper merchantBaseExtMapper;
	@Autowired
	private MerchantAccountMapper merchantAccountMapper;
	@Autowired
	private MerchantAccountJournalMapper merchantAccountJournalMapper;
	@Autowired
	private MerchantAccountJournalExtMapper merchantAccountJournalExtMapper;
	@Autowired
	private FreezeJournalMapper freezeJournalMapper;
	@Autowired
	private UnfreezeJournalMapper unfreezeJournalMapper;
	@Autowired
	private FinancialConfigurationBiz financialConfigurationBiz;
	
	@Value("${bountyHunter.balanceSaltValue}")
	private String balanceSaltValue;
	
	/**
	 * 企业账户开户
	 * 成功返回账户号
	 * @param customerAccount
	 */
	public Map<String, Object> openAccount(Map<String, Object> param){
		log.info("企业账户开户   请求参数：{}",param);
		Map<String, Object> respMap = new HashMap<String, Object>();
		String merId = (String) param.get("merId");
		String platformId = (String) param.get("platformId");
		String accType = (String) param.get("accType");
		
		MerchantBase merchantBase = merchantBaseMapper.selectByPrimaryKey(merId);
		if (null == merchantBase) {
			respMap.put("code", ResponseCode.MER_NOTEXIST.getCode());
			respMap.put("msg", ResponseCode.MER_NOTEXIST.getMessage());
			return respMap;
		}
		
		param.put("conType", "CON002");
		Map<String, Object> respPlatMap = platformAccoutConfigBiz.isExist(param);
		if (!ResponseCode.OK.getCode().equals(respPlatMap.get("code"))) {
			log.info("企业账户开户   响应参数：{}",respPlatMap);
			return respPlatMap;
		}
		
		MerchantAccount merchantAccountReq = new MerchantAccount();
		merchantAccountReq.setMerId(merId);
		merchantAccountReq.setAccType(accType);
		MerchantAccount merchantAccount = merchantAccountMapper.selectOne(merchantAccountReq);
		
		if (null == merchantAccount) {
			merchantAccount = new MerchantAccount();
			String accId = String.valueOf(SnowFlake.getId());
			merchantAccount.setAccId(accId);
			merchantAccount.setAccBalance(new BigDecimal("0.00"));
			merchantAccount.setChecksum(MD5.sign(merchantAccount.getAccBalance().toString(), balanceSaltValue, "utf-8"));
			merchantAccount.setCcy("CNY");
			merchantAccount.setMerId(merId);
			merchantAccount.setAccType(accType);
			merchantAccount.setAccountStatus("00");
			merchantAccount.setCreatetime(new Timestamp(System.currentTimeMillis()));
			merchantAccountMapper.insert(merchantAccount);
		}
		
		respMap.put("merchantAccount", merchantAccount);
		respMap.put("code", ResponseCode.OK.getCode());
		respMap.put("msg", ResponseCode.OK.getMessage());
		log.info("企业账户开户   响应参数：{}",respMap);
		return respMap;
	}
	
	/**
	 * 企业账户入金
	 * @param customerAccount
	 */
	public Map<String, Object> deposit(Map<String, Object> param){
		log.info("企业账户入金   请求参数：{}",param);
		Map<String, Object> respMap = new HashMap<String, Object>();
		String merId = (String) param.get("merId");
		String platformId = (String) param.get("platformId");
		String accType = (String) param.get("accType");
		String orderNo = (String) param.get("orderNo");
		String orderType = (String) param.get("orderType");
		String transferAmtStr = (String) param.get("transferAmt");
		BigDecimal transferAmt = new BigDecimal(transferAmtStr);
		
		Map<String, Object> reqBalMap = new HashMap<String, Object>();
		reqBalMap.put("merId", merId);
		reqBalMap.put("platformId", platformId);
		reqBalMap.put("accType", accType);
		Map<String, Object> openAccMap = openAccount(reqBalMap);
		if (!ResponseCode.OK.getCode().equals(openAccMap.get("code"))) {
			log.info("企业账户开户 异常参数：{}",openAccMap);
			return openAccMap;
		}
		MerchantAccount merchantAccount = (MerchantAccount) openAccMap.get("merchantAccount");
		
		boolean flag = MD5.verify(merchantAccount.getAccBalance().toString(), merchantAccount.getChecksum(), balanceSaltValue, "utf-8");
		if (flag) {
			merchantAccount.setAccBalance(merchantAccount.getAccBalance().add(transferAmt));
			merchantAccount.setChecksum(MD5.sign(merchantAccount.getAccBalance().toString(), balanceSaltValue, "utf-8"));
			merchantAccount.setUpdatetime(new Timestamp(System.currentTimeMillis()));
			merchantAccountMapper.updateByPrimaryKey(merchantAccount);
			
			MerchantAccountJournal intoMerchantAccountJournal = new MerchantAccountJournal();
			String intoJournalId = String.valueOf(SnowFlake.getId());
			intoMerchantAccountJournal.setJournalId(intoJournalId);
			intoMerchantAccountJournal.setAccId(merchantAccount.getAccId());
			intoMerchantAccountJournal.setPlatformId(platformId);
			intoMerchantAccountJournal.setOrderNo(orderNo);;
			intoMerchantAccountJournal.setMerId(merchantAccount.getMerId());
			intoMerchantAccountJournal.setAccType(accType);
			intoMerchantAccountJournal.setInOutFlag("1");//来账
			intoMerchantAccountJournal.setTradeAmt(transferAmt);
			intoMerchantAccountJournal.setTradeType(orderType);
			intoMerchantAccountJournal.setCreatetime(new Timestamp(System.currentTimeMillis()));
			merchantAccountJournalMapper.insert(intoMerchantAccountJournal);
			
			
			respMap.put("code", ResponseCode.OK.getCode());
			respMap.put("msg", ResponseCode.OK.getMessage());
		}else{
			respMap.put("code", ResponseCode.VERIFY_ACC_AMT.getCode());
			respMap.put("msg", ResponseCode.VERIFY_ACC_AMT.getMessage());
		}
		
		log.info("企业账户入金   响应参数：{}",respMap);
		return respMap;
	}
	
	/**
	 * 企业账户出金
	 * @param customerAccount
	 */
	public Map<String, Object> withdraw(Map<String, Object> param){
		log.info("企业账户出金   请求参数：{}",param);
		Map<String, Object> respMap = new HashMap<String, Object>();
		String merId = (String) param.get("merId");
		String platformId = (String) param.get("platformId");
		String accType = (String) param.get("accType");
		String orderNo = (String) param.get("orderNo");
		String orderType = (String) param.get("orderType");
		String transferAmtStr = (String) param.get("transferAmt");
		BigDecimal transferAmt = new BigDecimal(transferAmtStr);
		
		
		Map<String, Object> reqBalMap = new HashMap<String, Object>();
		reqBalMap.put("merId", merId);
		reqBalMap.put("platformId", platformId);
		reqBalMap.put("accType", accType);
		Map<String, Object> openAccMap = openAccount(reqBalMap);
		if (!ResponseCode.OK.getCode().equals(openAccMap.get("code"))) {
			log.info("企业账户开户 异常参数：{}",openAccMap);
			return openAccMap;
		}
		MerchantAccount merchantAccount = (MerchantAccount) openAccMap.get("merchantAccount");
		
			
		if ("00".equals(merchantAccount.getAccountStatus())) {
			// 企业转出账户正常
			boolean flag = MD5.verify(merchantAccount.getAccBalance().toString(), merchantAccount.getChecksum(), balanceSaltValue, "utf-8");
			if (flag) {
				if (merchantAccount.getAccBalance().compareTo(transferAmt) >= 0) {
					merchantAccount.setAccBalance(merchantAccount.getAccBalance().subtract(transferAmt));
					merchantAccount.setChecksum(MD5.sign(merchantAccount.getAccBalance().toString(), balanceSaltValue, "utf-8"));
					merchantAccount.setUpdatetime(new Timestamp(System.currentTimeMillis()));
					merchantAccountMapper.updateByPrimaryKey(merchantAccount);
					
					
					MerchantAccountJournal merchantAccountJournal = new MerchantAccountJournal();
					String journalId = String.valueOf(SnowFlake.getId());
					merchantAccountJournal.setJournalId(journalId);
					merchantAccountJournal.setAccId(merchantAccount.getAccId());
					merchantAccountJournal.setPlatformId(platformId);
					merchantAccountJournal.setOrderNo(orderNo);;
					merchantAccountJournal.setMerId(merchantAccount.getMerId());
					merchantAccountJournal.setAccType(accType);
					merchantAccountJournal.setInOutFlag("2");//往账
					merchantAccountJournal.setTradeAmt(transferAmt);
					merchantAccountJournal.setTradeType(orderType);
					merchantAccountJournal.setCreatetime(new Timestamp(System.currentTimeMillis()));
					merchantAccountJournalMapper.insert(merchantAccountJournal);
					
					respMap.put("code", ResponseCode.OK.getCode());
					respMap.put("msg", ResponseCode.OK.getMessage());
				} else {
					respMap.put("code", ResponseCode.ACC_BALANCE_INSUFFICIENT.getCode());
					respMap.put("msg", ResponseCode.ACC_BALANCE_INSUFFICIENT.getMessage());
				}
			}else{
				respMap.put("code", ResponseCode.VERIFY_ACC_AMT.getCode());
				respMap.put("msg", ResponseCode.VERIFY_ACC_AMT.getMessage());
			}
		} else if("01".equals(merchantAccount.getAccountStatus())) {
			// 企业转出账户被冻结
			respMap.put("code", ResponseCode.MER_ACC_FREEZE.getCode());
			respMap.put("msg", ResponseCode.MER_ACC_FREEZE.getMessage());
		}
		
		log.info("企业账户出金   响应参数：{}",respMap);
		return respMap;
	}
	
	/**
	 * 系统内企业转账
	 * 转账给商家 intoCustomerAccType:00
	 * 转账给个人 intoCustomerAccType:01
	 * 转账给平台 intoCustomerAccType:02
	 * 1、判断转出账户是否存在
	 * 2、判断转出账户状态是否被冻结
	 * 2、判断账户余额是否大于转出金额
	 * 3、判断转入用户是否存在
	 * 4、判断转入用户账户类型是企业还是个人
	 * 5、判断转入账户是否存在
	 * 6、转出账户余额减少，转入账户余额增多
	 * @param Map
	 */
	public Map<String, Object> transfer(Map<String, Object> param){
		log.info("系统内企业转账   请求参数：{}",param);
		Map<String, Object> respMap = new HashMap<String, Object>();
		String merId = (String) param.get("merId");
//		String intoMobile = (String) param.get("intoMobile");
		String intoId = (String) param.get("intoId");
		String platformId = (String) param.get("platformId");
		String intoCustomerAccType = (String) param.get("intoCustomerAccType");
		String intoAccType = (String) param.get("intoAccType");
		String outAccType = (String) param.get("outAccType");
		String transferAmtStr = (String) param.get("transferAmt");
		BigDecimal transferAmt = new BigDecimal(transferAmtStr);
		String orderNo = (String) param.get("orderNo");
		String orderType = (String) param.get("orderType");
		
		
		Map<String, Object> reqBalMap = new HashMap<String, Object>();
		reqBalMap.put("merId", merId);
		reqBalMap.put("platformId", platformId);
		reqBalMap.put("accType", outAccType);
		Map<String, Object> openAccMap = openAccount(reqBalMap);
		if (!ResponseCode.OK.getCode().equals(openAccMap.get("code"))) {
			log.info("企业账户开户 异常参数：{}",openAccMap);
			return openAccMap;
		}
		MerchantAccount merchantAccount = (MerchantAccount) openAccMap.get("merchantAccount");

		if ("00".equals(merchantAccount.getAccountStatus())) {
			// 企业转出账户状态正常
			boolean flag = MD5.verify(merchantAccount.getAccBalance().toString(), merchantAccount.getChecksum(), balanceSaltValue, "utf-8");
			if (flag) {
				if (merchantAccount.getAccBalance().compareTo(transferAmt) >= 0) {
					// 转账给企业或平台
					if ("00".equals(intoCustomerAccType) || "02".equals(intoCustomerAccType)) {
						
						Map<String, Object> reqIntoBalMap = new HashMap<String, Object>();
						reqIntoBalMap.put("merId", intoId);
						reqIntoBalMap.put("platformId", platformId);
						reqIntoBalMap.put("accType", intoAccType);
						Map<String, Object> intoAccMap = openAccount(reqIntoBalMap);
						if (!ResponseCode.OK.getCode().equals(intoAccMap.get("code"))) {
							log.info("企业账户开户 异常参数：{}",intoAccMap);
							return intoAccMap;
						}
						MerchantAccount intoMerchantAccount = (MerchantAccount) intoAccMap.get("merchantAccount");
						
						Map<String, Object> reqOutMap = new HashMap<String, Object>();
						reqOutMap.put("merId", merchantAccount.getMerId());
						reqOutMap.put("platformId", platformId);
						reqOutMap.put("accType", outAccType);
						reqOutMap.put("orderNo", orderNo);
						reqOutMap.put("orderType", orderType);
						reqOutMap.put("transferAmt", transferAmtStr);
						respMap = withdraw(reqOutMap);
						if (ResponseCode.OK.getCode().equals(respMap.get("code"))) {
							Map<String, Object> reqIntoMap = new HashMap<String, Object>();
							reqIntoMap.put("merId", intoMerchantAccount.getMerId());
							reqIntoMap.put("platformId", platformId);
							reqIntoMap.put("accType", intoAccType);
							reqIntoMap.put("orderNo", orderNo);
							reqIntoMap.put("orderType", orderType);
							reqIntoMap.put("transferAmt", transferAmtStr);
							deposit(reqIntoMap);
						}
								
					// 转账给个人
					} else if ("01".equals(intoCustomerAccType)) {
						Map<String, Object> reqPerMap = new HashMap<String, Object>();
						reqPerMap.put("perId", intoId);
						reqPerMap.put("platformId", platformId);
						reqPerMap.put("accType", intoAccType);
						Map<String, Object> perAccMap = personalAccountBiz.openAccount(reqPerMap);
						if (!ResponseCode.OK.getCode().equals(perAccMap.get("code"))) {
							log.info("客户账户开户 异常参数：{}",perAccMap);
							return perAccMap;
						}
						PersonalAccount personalAccount = (PersonalAccount) perAccMap.get("personalAccount");
						
						
						Map<String, Object> reqOutMap = new HashMap<String, Object>();
						reqOutMap.put("merId", merchantAccount.getMerId());
						reqOutMap.put("platformId", platformId);
						reqOutMap.put("accType", outAccType);
						reqOutMap.put("orderNo", orderNo);
						reqOutMap.put("orderType", orderType);
						reqOutMap.put("transferAmt", transferAmtStr);
						respMap = withdraw(reqOutMap);
						if (ResponseCode.OK.getCode().equals(respMap.get("code"))) {
							personalAccount.setAccBalance(personalAccount.getAccBalance().add(transferAmt));
							personalAccount.setChecksum(MD5.sign(personalAccount.getAccBalance().toString(), balanceSaltValue, "utf-8"));
							personalAccountMapper.updateByPrimaryKey(personalAccount);
							
							
							PersonalAccountJournal personalAccountJournal = new PersonalAccountJournal();
							String perJournalId = String.valueOf(SnowFlake.getId());
							personalAccountJournal.setJournalId(perJournalId);
							personalAccountJournal.setAccId(personalAccount.getAccId());
							personalAccountJournal.setPlatformId(platformId);
							personalAccountJournal.setOrderNo(orderNo);
							personalAccountJournal.setPerId(intoId);
							personalAccountJournal.setAccType(intoAccType);
							personalAccountJournal.setInOutFlag("1");//来账
							personalAccountJournal.setTradeAmt(transferAmt);
							personalAccountJournal.setTradeType(orderType);
							personalAccountJournal.setCreatetime(new Timestamp(System.currentTimeMillis()));
							personalAccountJournalMapper.insert(personalAccountJournal);
							
							PersonalBilling personalBilling = new PersonalBilling();
							String billId = String.valueOf(SnowFlake.getId());
							personalBilling.setBillId(billId);
							personalBilling.setPlatformId(platformId);
							personalBilling.setPerId(intoId);
							personalBilling.setAccJournalId(perJournalId);
							personalBilling.setOrderNo(orderNo);
							personalBilling.setBillType(orderType);
							personalBilling.setInOutFlag("1");
							personalBilling.setTranAmt(transferAmt);
							personalBilling.setInflowId(merId);
							personalBilling.setInflowType(CustomerType.CUST_MERCHANT.getCode());
							personalBilling.setOutflowId(intoId);
							personalBilling.setOutflowType(CustomerType.CUST_PERSONAL.getCode());
							personalBilling.setPayWay(intoAccType );
							personalBillingMapper.insert(personalBilling);
							
							Date day=new Date();
							SimpleDateFormat df = new SimpleDateFormat("yyyyMM");
							Customer customerReq = new Customer();
							customerReq.setPerId(intoId);
							Customer customerResp = customerMapper.selectOne(customerReq);
							redisTemplate.opsForZSet().incrementScore(df.format(day)+platformId, customerResp.getMobile(), transferAmt.doubleValue());
							
							String radisListName = "RewardRecord" + platformId;
							RewardRecord rewardRecord = new RewardRecord();
							rewardRecord.setMobile(customerResp.getMobile());
							rewardRecord.setType(orderType);
							rewardRecord.setAmount(transferAmt.toString());
							redisTemplate.opsForList().leftPush(radisListName, rewardRecord);
							if(redisTemplate.opsForList().size(radisListName) > 20){
								redisTemplate.opsForList().trim(radisListName, 0, 19);
							}
							
							respMap.put("code", ResponseCode.OK.getCode());
							respMap.put("msg", ResponseCode.OK.getMessage());
						}
								
					}
				} else {
					respMap.put("code", ResponseCode.ACC_BALANCE_INSUFFICIENT.getCode());
					respMap.put("msg", ResponseCode.ACC_BALANCE_INSUFFICIENT.getMessage());
				}
			}else{
				respMap.put("code", ResponseCode.VERIFY_ACC_AMT.getCode());
				respMap.put("msg", ResponseCode.VERIFY_ACC_AMT.getMessage());
			}
		} else if("01".equals(merchantAccount.getAccountStatus())) {
			// 企业转出账户被冻结
			respMap.put("code", ResponseCode.MER_ACC_FREEZE.getCode());
			respMap.put("msg", ResponseCode.MER_ACC_FREEZE.getMessage());
		}
			
		log.info("系统内企业转账   响应参数：{}",respMap);
		return respMap;
	}

	/**
	 * 商户资金冻结（冻结余额）
	 * @author centerroot
	 * @time 创建时间:2018年6月1日上午9:57:08
	 * @param param
	 * @return
	 */
	public Map<String, Object> freeze(Map<String, Object> param){
		log.info("商户资金冻结   请求参数：{}",param);
		Map<String, Object> respMap = new HashMap<String, Object>();
		String merId = (String) param.get("merId");
		String freezeAmtString = (String) param.get("freezeAmt");
		String platformId = (String) param.get("platformId");
		String orderNo = (String) param.get("orderNo");
		String orderType = (String) param.get("orderType");
		String taskId = (String) param.get("taskId");
		BigDecimal freezeAmt = new BigDecimal(freezeAmtString);
		
		Map<String, Object> reqBalMap = new HashMap<String, Object>();
		reqBalMap.put("merId", merId);
		reqBalMap.put("platformId", platformId);
		reqBalMap.put("accType", AccountType.ACC_BALANCE.getCode());
		Map<String, Object> openAccMap = openAccount(reqBalMap);
		if (!ResponseCode.OK.getCode().equals(openAccMap.get("code"))) {
			log.info("企业账户开户 异常参数：{}",openAccMap);
			return openAccMap;
		}
		MerchantAccount merchantAccount = (MerchantAccount) openAccMap.get("merchantAccount");
		
		Map<String, Object> reqFreezeMap = new HashMap<String, Object>();
		reqFreezeMap.put("merId", merId);
		reqFreezeMap.put("platformId", platformId);
		reqFreezeMap.put("accType", AccountType.ACC_FREEZE.getCode());
		Map<String, Object> freezeAccMap = openAccount(reqFreezeMap);
		if (!ResponseCode.OK.getCode().equals(freezeAccMap.get("code"))) {
			log.info("企业账户开户 异常参数：{}",freezeAccMap);
			return freezeAccMap;
		}
		MerchantAccount merchantAccountFreeze = (MerchantAccount) freezeAccMap.get("merchantAccount");
		
		boolean accBalFlag = MD5.verify(merchantAccount.getAccBalance().toString(), merchantAccount.getChecksum(), balanceSaltValue, "utf-8");
		boolean accFreezeflag = MD5.verify(merchantAccountFreeze.getAccBalance().toString(), merchantAccountFreeze.getChecksum(), balanceSaltValue, "utf-8");
		if (accBalFlag && accFreezeflag) {
			// 账户正常
			if ("00".equals(merchantAccount.getAccountStatus())) {
				if (merchantAccount.getAccBalance().compareTo(freezeAmt) >= 0) {
					
					Map<String, Object> reqOutMap = new HashMap<String, Object>();
					reqOutMap.put("merId", merchantAccount.getMerId());
					reqOutMap.put("platformId", platformId);
					reqOutMap.put("accType", AccountType.ACC_BALANCE.getCode());
					reqOutMap.put("orderNo", orderNo);
					reqOutMap.put("orderType", orderType);
					reqOutMap.put("transferAmt", freezeAmtString);
					respMap = withdraw(reqOutMap);
					if (ResponseCode.OK.getCode().equals(respMap.get("code"))) {
						Map<String, Object> reqIntoMap = new HashMap<String, Object>();
						reqIntoMap.put("merId", merchantAccountFreeze.getMerId());
						reqIntoMap.put("platformId", platformId);
						reqIntoMap.put("accType", AccountType.ACC_FREEZE.getCode());
						reqIntoMap.put("orderNo", orderNo);
						reqIntoMap.put("orderType", orderType);
						reqIntoMap.put("transferAmt", freezeAmtString);
						deposit(reqIntoMap);
						
						
						FreezeJournal freezeJournal = new FreezeJournal();
						String freezeId = String.valueOf(SnowFlake.getId());
						freezeJournal.setJournalId(freezeId);
						freezeJournal.setOrderNo(orderNo);
						freezeJournal.setOrderType(orderType);
						freezeJournal.setConType("2");
						freezeJournal.setConAccId(merchantAccount.getAccId());
						freezeJournal.setBalance(freezeAmt);
						freezeJournal.setFreezeType("1");
						freezeJournal.setStatus("1");
						freezeJournal.setCreatetime(new Timestamp(System.currentTimeMillis()));
						freezeJournalMapper.insert(freezeJournal);
						
						respMap.put("freezeId", freezeId);
						respMap.put("code", ResponseCode.OK.getCode());
						respMap.put("msg", ResponseCode.OK.getMessage());
					}
				} else {
					respMap.put("code", ResponseCode.ACC_BALANCE_INSUFFICIENT.getCode());
					respMap.put("msg", ResponseCode.ACC_BALANCE_INSUFFICIENT.getMessage());
				}
			} else if("01".equals(merchantAccount.getAccountStatus())) {
				// 账户被冻结
				respMap.put("code", ResponseCode.PER_ACC_FREEZE.getCode());
				respMap.put("msg", ResponseCode.PER_ACC_FREEZE.getMessage());
			}
		}else{
			respMap.put("code", ResponseCode.VERIFY_ACC_AMT.getCode());
			respMap.put("msg", ResponseCode.VERIFY_ACC_AMT.getMessage());
		}
		
		log.info("商户资金冻结   响应参数：{}",respMap);
		return respMap;
	}
	
	
	/**
	 * 商户资金解冻（可部分解冻）
	 * @author centerroot
	 * @time 创建时间:2018年6月1日下午1:47:50
	 * @param param
	 * @return
	 */
	public Map<String, Object> unfreeze(Map<String, Object> param){
		log.info("商户资金解冻（可部分解冻）   请求参数：{}",param);
		Map<String, Object> respMap = new HashMap<String, Object>();
		String merId = (String) param.get("merId");
		String freezeId = (String) param.get("freezeId");
		String unfreezeAmtStr = (String) param.get("unfreezeAmt");
		BigDecimal unfreezeAmt = new BigDecimal(unfreezeAmtStr);
		String platformId = (String) param.get("platformId");
		String orderNo = (String) param.get("orderNo");
		String orderType = (String) param.get("orderType");
		
		Map<String, Object> reqBalMap = new HashMap<String, Object>();
		reqBalMap.put("merId", merId);
		reqBalMap.put("platformId", platformId);
		reqBalMap.put("accType", AccountType.ACC_BALANCE.getCode());
		Map<String, Object> merAccMap = openAccount(reqBalMap);
		if (!ResponseCode.OK.getCode().equals(merAccMap.get("code"))) {
			log.info("企业账户开户 异常参数：{}",merAccMap);
			return merAccMap;
		}
		MerchantAccount merchantAccount = (MerchantAccount) merAccMap.get("merchantAccount");
		
		Map<String, Object> reqFreezeMap = new HashMap<String, Object>();
		reqFreezeMap.put("merId", merId);
		reqFreezeMap.put("platformId", platformId);
		reqFreezeMap.put("accType", AccountType.ACC_FREEZE.getCode());
		Map<String, Object> freezeAccMap = openAccount(reqFreezeMap);
		if (!ResponseCode.OK.getCode().equals(freezeAccMap.get("code"))) {
			log.info("企业账户开户 异常参数：{}",freezeAccMap);
			return freezeAccMap;
		}
		MerchantAccount merchantAccountFreeze = (MerchantAccount) freezeAccMap.get("merchantAccount");
		
		boolean accBalFlag = MD5.verify(merchantAccount.getAccBalance().toString(), merchantAccount.getChecksum(), balanceSaltValue, "utf-8");
		boolean accFreezeflag = MD5.verify(merchantAccountFreeze.getAccBalance().toString(), merchantAccountFreeze.getChecksum(), balanceSaltValue, "utf-8");
		
		if (accBalFlag && accFreezeflag) {
			if (merchantAccountFreeze.getAccBalance().compareTo(unfreezeAmt) >= 0) {
				// 冻结账户余额大于解冻金额
				if ("00".equals(merchantAccount.getAccountStatus())) {
					// 账户正常
					FreezeJournal freezeJournal = freezeJournalMapper.selectByPrimaryKey(freezeId);
					if (null != freezeJournal) {
						BigDecimal unfreezeTotal = BigDecimal.ZERO;
						UnfreezeJournal unfreezeJournalReq = new UnfreezeJournal();
						unfreezeJournalReq.setFreezeId(freezeId);
						List<UnfreezeJournal> unfreezeJournals = unfreezeJournalMapper.select(unfreezeJournalReq);
						if (null != unfreezeJournals && unfreezeJournals.size() > 0) {
							for (int i = 0; i < unfreezeJournals.size(); i++) {
								unfreezeTotal = unfreezeTotal.add(unfreezeJournals.get(i).getBalance());
							}
						}
						unfreezeTotal = unfreezeTotal.add(unfreezeAmt);
						if (unfreezeTotal.compareTo(freezeJournal.getBalance()) <= 0) {
							
							Map<String, Object> reqOutMap = new HashMap<String, Object>();
							reqOutMap.put("merId", merchantAccountFreeze.getMerId());
							reqOutMap.put("platformId", platformId);
							reqOutMap.put("accType", AccountType.ACC_FREEZE.getCode());
							reqOutMap.put("orderNo", orderNo);
							reqOutMap.put("orderType", orderType);
							reqOutMap.put("transferAmt", unfreezeAmtStr);
							respMap = withdraw(reqOutMap);

							if (ResponseCode.OK.getCode().equals(respMap.get("code"))) {
								Map<String, Object> reqIntoMap = new HashMap<String, Object>();
								reqIntoMap.put("merId", merchantAccount.getMerId());
								reqIntoMap.put("platformId", platformId);
								reqIntoMap.put("accType", AccountType.ACC_BALANCE.getCode());
								reqIntoMap.put("orderNo", orderNo);
								reqIntoMap.put("orderType", orderType);
								reqIntoMap.put("transferAmt", unfreezeAmtStr);
								respMap = deposit(reqIntoMap);
								
								if (ResponseCode.OK.getCode().equals(respMap.get("code"))) {
									UnfreezeJournal unfreezeJournal = new UnfreezeJournal();
									String unfreezeId = String.valueOf(SnowFlake.getId());
									unfreezeJournal.setJournalId(unfreezeId);
									unfreezeJournal.setOrderNo(orderNo);
									unfreezeJournal.setOrderType(orderType);
									unfreezeJournal.setFreezeId(freezeId);
									unfreezeJournal.setBalance(unfreezeAmt);
									unfreezeJournal.setCreatetime(new Timestamp(System.currentTimeMillis()));
									unfreezeJournalMapper.insert(unfreezeJournal);
									
									if (unfreezeTotal.compareTo(freezeJournal.getBalance()) < 0) {
										freezeJournal.setStatus("2"); // 部分解冻
										freezeJournalMapper.updateByPrimaryKey(freezeJournal);
									}else if (unfreezeTotal.compareTo(freezeJournal.getBalance()) == 0) {
										freezeJournal.setStatus("3"); // 已解冻
										freezeJournalMapper.updateByPrimaryKey(freezeJournal);
									}
								}
							}

						} else {
							respMap.put("code", ResponseCode.FREEZE_UNFREEZE_AMT_INCONSISTEND.getCode());
							respMap.put("msg", ResponseCode.FREEZE_UNFREEZE_AMT_INCONSISTEND.getMessage());
						}
					} else {
						respMap.put("code", ResponseCode.FREEZE_ID_NOTEXIST.getCode());
						respMap.put("msg", ResponseCode.FREEZE_ID_NOTEXIST.getMessage());
					}
					
				} else if("01".equals(merchantAccount.getAccountStatus())) {
					// 账户被冻结
					respMap.put("code", ResponseCode.PER_ACC_FREEZE.getCode());
					respMap.put("msg", ResponseCode.PER_ACC_FREEZE.getMessage());
				}
			}else{
				respMap.put("code", ResponseCode.ACC_BALANCE_INSUFFICIENT.getCode());
				respMap.put("msg", ResponseCode.ACC_BALANCE_INSUFFICIENT.getMessage());
				log.info("商户资金解冻（可部分解冻）【冻结账户余额不足】   响应参数：{}",respMap);
			}
		}else{
			respMap.put("code", ResponseCode.VERIFY_ACC_AMT.getCode());
			respMap.put("msg", ResponseCode.VERIFY_ACC_AMT.getMessage());
		}
		
		log.info("商户资金解冻（可部分解冻）   响应参数：{}",respMap);
		return respMap;
	}
	
	/**
	 * 解冻并出账
	 * 转账给商家 intoCustomerAccType:00
	 * 转账给个人 intoCustomerAccType:01
	 * 转账给平台 intoCustomerAccType:02
	 * @author centerroot
	 * @time 创建时间:2018年6月4日下午3:18:45
	 * @param param
	 * @return
	 */
	public Map<String, Object> unfreezeTransfer(Map<String, Object> param){
		log.info("解冻并出账   请求参数：{}",param);
		Map<String, Object> respMap = new HashMap<String, Object>();
		String merId = (String) param.get("merId");
		String intoId = (String) param.get("intoId");
		String freezeId = (String) param.get("freezeId");
		String unfreezeAmtStr = (String) param.get("unfreezeAmt");
		String platformServiceFeeStr = (String) param.get("platformServiceFee");
		String platformManagementFeeStr = (String) param.get("platformManagementFee");
		BigDecimal unfreezeAmt = new BigDecimal(unfreezeAmtStr);
		BigDecimal platformServiceFee = new BigDecimal(platformServiceFeeStr);
		BigDecimal platformManagementFee = new BigDecimal(platformManagementFeeStr);
		BigDecimal transferAmt = unfreezeAmt.subtract(platformServiceFee).subtract(platformManagementFee);
		String intoCustomerAccType = (String) param.get("intoCustomerAccType");
		String platformId = (String) param.get("platformId");
		String orderNo = (String) param.get("orderNo");
		String orderType = (String) param.get("orderType");
		
		Customer customerRequest = new Customer();
		customerRequest.setPlatformId(platformId);
		customerRequest.setCustomerType("00"); // 平台
		Customer customer = customerMapper.selectOne(customerRequest);
		if (null == customer) {
			respMap.put("code", ResponseCode.CUST_NOTEXIST.getCode());
			respMap.put("msg", ResponseCode.CUST_NOTEXIST.getMessage());
			log.info("解冻并出账 【冻结账户余额不足】   平台信息不存在");
		}
		
		Map<String, Object> reqPlatMngMap = new HashMap<String, Object>();
		reqPlatMngMap.put("merId", customer.getMerId());
		reqPlatMngMap.put("platformId", platformId);
		reqPlatMngMap.put("accType", AccountType.ACC_PLATFORM_MANAGEMENT.getCode());
		Map<String, Object> respPlatMngMap = openAccount(reqPlatMngMap);
		if (!ResponseCode.OK.getCode().equals(respPlatMngMap.get("code"))) {
			log.info("企业账户开户 异常参数：{}",respPlatMngMap);
			return respPlatMngMap;
		}
		MerchantAccount PlatMngAccount = (MerchantAccount) respPlatMngMap.get("merchantAccount");
		
		Map<String, Object> reqPlatServiceMap = new HashMap<String, Object>();
		reqPlatServiceMap.put("merId", customer.getMerId());
		reqPlatServiceMap.put("platformId", platformId);
		reqPlatServiceMap.put("accType", AccountType.ACC_PLATFORM_SERVICE.getCode());
		Map<String, Object> respPlatServiceMap = openAccount(reqPlatServiceMap);
		if (!ResponseCode.OK.getCode().equals(respPlatServiceMap.get("code"))) {
			log.info("企业账户开户 异常参数：{}",respPlatServiceMap);
			return respPlatServiceMap;
		}
		MerchantAccount PlatServiceAccount = (MerchantAccount) respPlatServiceMap.get("merchantAccount");
		
		Map<String, Object> reqFreezeMap = new HashMap<String, Object>();
		reqFreezeMap.put("merId", merId);
		reqFreezeMap.put("platformId", platformId);
		reqFreezeMap.put("accType", AccountType.ACC_FREEZE.getCode());
		Map<String, Object> merFreezeAccMap = openAccount(reqFreezeMap);
		if (!ResponseCode.OK.getCode().equals(merFreezeAccMap.get("code"))) {
			log.info("企业账户开户 异常参数：{}",merFreezeAccMap);
			return merFreezeAccMap;
		}
		MerchantAccount merchantAccountFreeze = (MerchantAccount) merFreezeAccMap.get("merchantAccount");
		
		// 转账给企业或平台
		if ("00".equals(intoCustomerAccType) || "02".equals(intoCustomerAccType)) {
			Map<String, Object> reqBalMap = new HashMap<String, Object>();
			reqBalMap.put("merId", intoId);
			reqBalMap.put("platformId", platformId);
			reqBalMap.put("accType", AccountType.ACC_BALANCE.getCode());
			Map<String, Object> merAccMap = openAccount(reqBalMap);
			if (!ResponseCode.OK.getCode().equals(merAccMap.get("code"))) {
				log.info("企业账户开户 异常参数：{}",merAccMap);
				return merAccMap;
			}
			MerchantAccount merchantAccount = (MerchantAccount) merAccMap.get("merchantAccount");
			
			boolean accBalFlag = MD5.verify(merchantAccount.getAccBalance().toString(), merchantAccount.getChecksum(), balanceSaltValue, "utf-8");
			boolean accFreezeflag = MD5.verify(merchantAccountFreeze.getAccBalance().toString(), merchantAccountFreeze.getChecksum(), balanceSaltValue, "utf-8");
			
			if (accBalFlag && accFreezeflag) {
				if (merchantAccountFreeze.getAccBalance().compareTo(unfreezeAmt) >= 0) {
					FreezeJournal freezeJournal = freezeJournalMapper.selectByPrimaryKey(freezeId);
					if (null != freezeJournal) {
						BigDecimal unfreezeTotal = BigDecimal.ZERO;
						UnfreezeJournal unfreezeJournalReq = new UnfreezeJournal();
						unfreezeJournalReq.setFreezeId(freezeId);
						List<UnfreezeJournal> unfreezeJournals = unfreezeJournalMapper.select(unfreezeJournalReq);
						if (null != unfreezeJournals && unfreezeJournals.size() > 0) {
							for (int i = 0; i < unfreezeJournals.size(); i++) {
								unfreezeTotal = unfreezeTotal.add(unfreezeJournals.get(i).getBalance());
							}
						}
						unfreezeTotal = unfreezeTotal.add(unfreezeAmt);
						if (unfreezeTotal.compareTo(freezeJournal.getBalance()) <= 0) {
							
							Map<String, Object> reqOutMap = new HashMap<String, Object>();
							reqOutMap.put("merId", merchantAccountFreeze.getMerId());
							reqOutMap.put("platformId", platformId);
							reqOutMap.put("accType", AccountType.ACC_FREEZE.getCode());
							reqOutMap.put("orderNo", orderNo);
							reqOutMap.put("orderType", orderType);
							reqOutMap.put("transferAmt", unfreezeAmtStr);
							respMap = withdraw(reqOutMap);
							log.info("企业冻结账户出账结果：{}",respMap);
							if (ResponseCode.OK.getCode().equals(respMap.get("code"))) {
								Map<String, Object> reqIntoMap = new HashMap<String, Object>();
								reqIntoMap.put("merId", merchantAccount.getMerId());
								reqIntoMap.put("platformId", platformId);
								reqIntoMap.put("accType", AccountType.ACC_BALANCE.getCode());
								reqIntoMap.put("orderNo", orderNo);
								reqIntoMap.put("orderType", orderType);
								reqIntoMap.put("transferAmt", transferAmt.toString());
								respMap = deposit(reqIntoMap);
								log.info("企业余额账户入账结果：{}",respMap);
								
								Map<String, Object> platMngMap = new HashMap<String, Object>();
								platMngMap.put("merId", PlatMngAccount.getMerId());
								platMngMap.put("platformId", platformId);
								platMngMap.put("accType", AccountType.ACC_PLATFORM_MANAGEMENT.getCode());
								platMngMap.put("orderNo", orderNo);
								platMngMap.put("orderType", orderType);
								platMngMap.put("transferAmt", platformManagementFeeStr);
								respMap = deposit(platMngMap);
								log.info("平台管理账户入账结果：{}",respMap);
								
								Map<String, Object> platServiceMap = new HashMap<String, Object>();
								platServiceMap.put("merId", PlatServiceAccount.getMerId());
								platServiceMap.put("platformId", platformId);
								platServiceMap.put("accType", AccountType.ACC_PLATFORM_SERVICE.getCode());
								platServiceMap.put("orderNo", orderNo);
								platServiceMap.put("orderType", orderType);
								platServiceMap.put("transferAmt", platformServiceFeeStr);
								respMap = deposit(platServiceMap);
								log.info("平台服务账户入账结果：{}",respMap);
								
								UnfreezeJournal unfreezeJournal = new UnfreezeJournal();
								String unfreezeId = String.valueOf(SnowFlake.getId());
								unfreezeJournal.setJournalId(unfreezeId);
								unfreezeJournal.setOrderNo(orderNo);
								unfreezeJournal.setOrderType(orderType);
								unfreezeJournal.setFreezeId(freezeId);
								unfreezeJournal.setBalance(unfreezeAmt);
								unfreezeJournal.setCreatetime(new Timestamp(System.currentTimeMillis()));
								unfreezeJournalMapper.insert(unfreezeJournal);
							}

						} else {
							respMap.put("code", ResponseCode.FREEZE_UNFREEZE_AMT_INCONSISTEND.getCode());
							respMap.put("msg", ResponseCode.FREEZE_UNFREEZE_AMT_INCONSISTEND.getMessage());
						}
					} else {
						respMap.put("code", ResponseCode.FREEZE_ID_NOTEXIST.getCode());
						respMap.put("msg", ResponseCode.FREEZE_ID_NOTEXIST.getMessage());
					}
				}else{
					respMap.put("code", ResponseCode.ACC_BALANCE_INSUFFICIENT.getCode());
					respMap.put("msg", ResponseCode.ACC_BALANCE_INSUFFICIENT.getMessage());
					log.info("解冻并出账 【冻结账户余额不足】   响应参数：{}",respMap);
				}
			}else{
				respMap.put("code", ResponseCode.VERIFY_ACC_AMT.getCode());
				respMap.put("msg", ResponseCode.VERIFY_ACC_AMT.getMessage());
			}
			
		// 转账给个人
		} else if ("01".equals(intoCustomerAccType)) {
				Map<String, Object> reqPerMap = new HashMap<String, Object>();
				reqPerMap.put("perId", intoId);
				reqPerMap.put("platformId", platformId);
				reqPerMap.put("accType", AccountType.ACC_BALANCE.getCode());
				Map<String, Object> perAccMap = personalAccountBiz.openAccount(reqPerMap);
				if (!ResponseCode.OK.getCode().equals(perAccMap.get("code"))) {
					log.info("客户账户开户 异常参数：{}",perAccMap);
					return perAccMap;
				}
				PersonalAccount personalAccount = (PersonalAccount) perAccMap.get("personalAccount");
				
				boolean accBalFlag = MD5.verify(personalAccount.getAccBalance().toString(), personalAccount.getChecksum(), balanceSaltValue, "utf-8");
				boolean accFreezeflag = MD5.verify(merchantAccountFreeze.getAccBalance().toString(), merchantAccountFreeze.getChecksum(), balanceSaltValue, "utf-8");
				
				if (accBalFlag && accFreezeflag) {
					if (merchantAccountFreeze.getAccBalance().compareTo(unfreezeAmt) >= 0) {
						FreezeJournal freezeJournal = freezeJournalMapper.selectByPrimaryKey(freezeId);
						if (null != freezeJournal) {
							BigDecimal unfreezeTotal = BigDecimal.ZERO;
							UnfreezeJournal unfreezeJournalReq = new UnfreezeJournal();
							unfreezeJournalReq.setFreezeId(freezeId);
							List<UnfreezeJournal> unfreezeJournals = unfreezeJournalMapper.select(unfreezeJournalReq);
							if (null != unfreezeJournals && unfreezeJournals.size() > 0) {
								for (int i = 0; i < unfreezeJournals.size(); i++) {
									unfreezeTotal = unfreezeTotal.add(unfreezeJournals.get(i).getBalance());
								}
							}
							unfreezeTotal = unfreezeTotal.add(unfreezeAmt);
							if (unfreezeTotal.compareTo(freezeJournal.getBalance()) <= 0) {
								
								Map<String, Object> reqOutMap = new HashMap<String, Object>();
								reqOutMap.put("merId", merchantAccountFreeze.getMerId());
								reqOutMap.put("platformId", platformId);
								reqOutMap.put("accType", AccountType.ACC_FREEZE.getCode());
								reqOutMap.put("orderNo", orderNo);
								reqOutMap.put("orderType", orderType);
								reqOutMap.put("transferAmt", unfreezeAmtStr);
								respMap = withdraw(reqOutMap);
								log.info("企业冻结账户出账结果：{}",respMap);

								if (ResponseCode.OK.getCode().equals(respMap.get("code"))) {
									personalAccount.setAccBalance(personalAccount.getAccBalance().add(transferAmt));
									personalAccount.setChecksum(MD5.sign(personalAccount.getAccBalance().toString(), balanceSaltValue, "utf-8"));
									merchantAccountMapper.updateByPrimaryKey(merchantAccountFreeze);
									personalAccountMapper.updateByPrimaryKey(personalAccount);
									
									PersonalAccountJournal personalAccountJournal = new PersonalAccountJournal();
									String perJournalId = String.valueOf(SnowFlake.getId());
									personalAccountJournal.setJournalId(perJournalId);
									personalAccountJournal.setAccId(personalAccount.getAccId());
									personalAccountJournal.setPlatformId(platformId);
									personalAccountJournal.setOrderNo(orderNo);
									personalAccountJournal.setPerId(intoId);
									personalAccountJournal.setAccType(AccountType.ACC_BALANCE.getCode());
									personalAccountJournal.setInOutFlag("1");//来账
									personalAccountJournal.setTradeAmt(transferAmt);
									personalAccountJournal.setTradeType(orderType);
									personalAccountJournal.setCreatetime(new Timestamp(System.currentTimeMillis()));
									personalAccountJournalMapper.insert(personalAccountJournal);
									
									PersonalBilling personalBilling = new PersonalBilling();
									String billId = String.valueOf(SnowFlake.getId());
									personalBilling.setBillId(billId);
									personalBilling.setPlatformId(platformId);
									personalBilling.setPerId(intoId);
									personalBilling.setAccJournalId(perJournalId);
									personalBilling.setOrderNo(orderNo);
									personalBilling.setBillType(orderType);
									personalBilling.setInOutFlag("1");
									personalBilling.setTranAmt(transferAmt);
									personalBilling.setInflowId(merId);
									personalBilling.setInflowType(CustomerType.CUST_MERCHANT.getCode());
									personalBilling.setOutflowId(intoId);
									personalBilling.setOutflowType(CustomerType.CUST_PERSONAL.getCode());
									personalBilling.setPayWay(AccountType.ACC_FREEZE.getCode());
									personalBillingMapper.insert(personalBilling);
									
									Map<String, Object> platMngMap = new HashMap<String, Object>();
									platMngMap.put("merId", PlatMngAccount.getMerId());
									platMngMap.put("platformId", platformId);
									platMngMap.put("accType", AccountType.ACC_PLATFORM_MANAGEMENT.getCode());
									platMngMap.put("orderNo", orderNo);
									platMngMap.put("orderType", orderType);
									platMngMap.put("transferAmt", platformManagementFeeStr);
									respMap = deposit(platMngMap);
									log.info("平台管理账户入账结果：{}",respMap);
									
									Map<String, Object> platServiceMap = new HashMap<String, Object>();
									platServiceMap.put("merId", PlatServiceAccount.getMerId());
									platServiceMap.put("platformId", platformId);
									platServiceMap.put("accType", AccountType.ACC_PLATFORM_SERVICE.getCode());
									platServiceMap.put("orderNo", orderNo);
									platServiceMap.put("orderType", orderType);
									platServiceMap.put("transferAmt", platformServiceFeeStr);
									respMap = deposit(platServiceMap);
									log.info("平台服务账户入账结果：{}",respMap);
									
									UnfreezeJournal unfreezeJournal = new UnfreezeJournal();
									String unfreezeId = String.valueOf(SnowFlake.getId());
									unfreezeJournal.setJournalId(unfreezeId);
									unfreezeJournal.setOrderNo(orderNo);
									unfreezeJournal.setOrderType(orderType);
									unfreezeJournal.setFreezeId(freezeId);
									unfreezeJournal.setBalance(unfreezeAmt);
									unfreezeJournal.setCreatetime(new Timestamp(System.currentTimeMillis()));
									unfreezeJournalMapper.insert(unfreezeJournal);
									
									
									Date day=new Date();
									SimpleDateFormat df = new SimpleDateFormat("yyyyMM");
									Customer customerReq = new Customer();
									customerReq.setPerId(intoId);
									Customer customerResp = customerMapper.selectOne(customerReq);
									redisTemplate.opsForZSet().incrementScore(df.format(day)+platformId, customerResp.getMobile(), unfreezeAmt.doubleValue());
									
									String radisListName = "RewardRecord" + platformId;
									RewardRecord rewardRecord = new RewardRecord();
									rewardRecord.setMobile(customerResp.getMobile());
									rewardRecord.setType(orderType);
									rewardRecord.setAmount(unfreezeAmt.toString());
									redisTemplate.opsForList().leftPush(radisListName, rewardRecord);
									if(redisTemplate.opsForList().size(radisListName) > 10){
										redisTemplate.opsForList().trim(radisListName, 0, 9);
									}
									
									respMap.put("code", ResponseCode.OK.getCode());
									respMap.put("msg", ResponseCode.OK.getMessage());
								}
								
							} else {
								respMap.put("code", ResponseCode.FREEZE_UNFREEZE_AMT_INCONSISTEND.getCode());
								respMap.put("msg", ResponseCode.FREEZE_UNFREEZE_AMT_INCONSISTEND.getMessage());
							}
						} else {
							respMap.put("code", ResponseCode.FREEZE_ID_NOTEXIST.getCode());
							respMap.put("msg", ResponseCode.FREEZE_ID_NOTEXIST.getMessage());
						}
					}else{
						respMap.put("code", ResponseCode.ACC_BALANCE_INSUFFICIENT.getCode());
						respMap.put("msg", ResponseCode.ACC_BALANCE_INSUFFICIENT.getMessage());
						log.info("解冻并出账 【冻结账户余额不足】   响应参数：{}",respMap);
					}
				}else{
					respMap.put("code", ResponseCode.VERIFY_ACC_AMT.getCode());
					respMap.put("msg", ResponseCode.VERIFY_ACC_AMT.getMessage());
				}
				
		}
		
		log.info("解冻并出账   响应参数：{}",respMap);
		return respMap;
	}
	
	/**
	 * 企业邀请面试扣除次数或金额
	 * @author centerroot
	 * @time 创建时间:2018年6月4日下午6:50:36
	 * @param param
	 * @return
	 */
	public Map<String, Object> inviteToInterview(Map<String, Object> param){
		log.info("企业邀请面试扣除次数或金额   请求参数：{}",param);
		Map<String, Object> respMap = new HashMap<String, Object>();
		String merId = (String) param.get("merId");
		String perId = (String) param.get("perId");//登录会员编号
		String platformId = (String) param.get("platformId");
		String orderNo = (String) param.get("orderNo");
		String orderType = (String) param.get("orderType");
		
		MerchantBase merchantBase = merchantBaseMapper.selectByPrimaryKey(merId);
		PersonalBase personalBase = personalBaseMapper.selectByPrimaryKey(perId);
		if (null == merchantBase) {
			respMap.put("code", ResponseCode.MER_NOTEXIST.getCode());
			respMap.put("msg", ResponseCode.MER_NOTEXIST.getMessage());
			log.info("企业邀请面试扣除次数或金额(转出企业账户不存在)   响应参数：{}",respMap);
			return respMap;
		}
		if (null == personalBase) {
			respMap.put("code", ResponseCode.PER_NOTEXIST.getCode());
			respMap.put("msg", ResponseCode.PER_NOTEXIST.getMessage());
			log.info("企业邀请面试扣除次数或金额（转入个人账户不存在）   响应参数：{}",respMap);
			return respMap;
		}
		
		Map<String, Object> reqBalMap = new HashMap<String, Object>();
		reqBalMap.put("merId", merId);
		reqBalMap.put("platformId", platformId);
		reqBalMap.put("accType", AccountType.ACC_BALANCE.getCode());
		Map<String, Object> merAccMap = openAccount(reqBalMap);
		if (!ResponseCode.OK.getCode().equals(merAccMap.get("code"))) {
			log.info("企业账户开户 异常参数：{}",merAccMap);
			return merAccMap;
		}
		MerchantAccount merchantAccount = (MerchantAccount) merAccMap.get("merchantAccount");
		
		Customer customerReq = new Customer();
		customerReq.setPlatformId(platformId);
		customerReq.setCustomerType("00"); // 平台
		Customer customer = customerMapper.selectOne(customerReq);
		if (null != customer) {
			log.info("平台账户查询用户基础信息   请求参数：{}",EntityUtils.beanToMap(customer));
			
			MerchantBase platformBase = merchantBaseMapper.selectByPrimaryKey(customer.getMerId());
			if (null == platformBase) {
				respMap.put("code", ResponseCode.MER_NOTEXIST.getCode());
				respMap.put("msg", ResponseCode.MER_NOTEXIST.getMessage());
				log.info("企业邀请面试扣除次数或金额（平台企业账户信息不存在）   响应参数：{}",respMap);
				return respMap;
			}
			
			MerchantBaseExt merchantBaseExt = merchantBaseExtMapper.selectByPrimaryKey(merId);
			
			Map<String, Object> reqResumeMap = new HashMap<String, Object>();
			reqResumeMap.put("platformId", platformId);
			Map<String, Object> resumeDeductionMap = financialConfigurationBiz.platformResumeDeductionAmt(reqResumeMap);
			Map<String, Object> resumeSubsidiesMap = financialConfigurationBiz.platformResumeSubsidiesAmt(reqResumeMap);
			// TODO 悬赏者邀请面试扣除金额和猎手的简历补贴金额暂时写死
			if (null != merchantBaseExt && merchantBaseExt.getInterview() > 0) {
				merchantBaseExt.setInterview(merchantBaseExt.getInterview()-1);
				merchantBaseExtMapper.updateByPrimaryKey(merchantBaseExt);
				Map<String, Object> reqTransferMap = new HashMap<String, Object>();
				reqTransferMap.put("merId", platformBase.getMerId());
				reqTransferMap.put("intoId", perId);
				reqTransferMap.put("platformId", platformId);
				reqTransferMap.put("intoCustomerAccType", "01");
				reqTransferMap.put("intoAccType", AccountType.ACC_BALANCE.getCode());
				reqTransferMap.put("outAccType", AccountType.ACC_BALANCE.getCode());
				reqTransferMap.put("transferAmt", resumeSubsidiesMap.get("amount"));  // 猎手获得简历补贴
				reqTransferMap.put("orderNo", orderNo);
				reqTransferMap.put("orderType", orderType);
				respMap = transfer(reqTransferMap);
				
			} else if (merchantAccount.getAccBalance().compareTo(BigDecimal.valueOf(10)) >= 0) {
				Map<String, Object> reqTransferMap = new HashMap<String, Object>();
				reqTransferMap.put("merId", merId);
				reqTransferMap.put("intoId", platformBase.getMerId());
				reqTransferMap.put("platformId", platformId);
				reqTransferMap.put("intoCustomerAccType", "02");
				reqTransferMap.put("intoAccType", AccountType.ACC_BALANCE.getCode());
				reqTransferMap.put("outAccType", AccountType.ACC_BALANCE.getCode());
				reqTransferMap.put("transferAmt", resumeDeductionMap.get("amount"));// 悬赏方扣除金额
				reqTransferMap.put("orderNo", orderNo);
				reqTransferMap.put("orderType", orderType);
				respMap = transfer(reqTransferMap);
				if (ResponseCode.OK.getCode().equals(respMap.get("code"))) {
					reqTransferMap.put("merId", platformBase.getMerId());
					reqTransferMap.put("intoId", perId);
					reqTransferMap.put("intoCustomerAccType", "01");
					reqTransferMap.put("transferAmt", resumeSubsidiesMap.get("amount"));  // 猎手获得简历补贴
					respMap = transfer(reqTransferMap);
				}
			} else {
				respMap.put("code", ResponseCode.ACC_BALANCE_INSUFFICIENT.getCode());
				respMap.put("msg", ResponseCode.ACC_BALANCE_INSUFFICIENT.getMessage());
			}
		} else {
			respMap.put("code", ResponseCode.CUST_NOTEXIST.getCode());
			respMap.put("msg", ResponseCode.CUST_NOTEXIST.getMessage());
		}
		log.info("企业邀请面试扣除次数或金额   响应参数：{}",respMap);
		return respMap;
	}
	
	
	/**
	 * 线下充值调用接口
	 * 商家充值   Type:00
	 * 平台充值   Type:01
	 * @author centerroot
	 * @time 创建时间:2018年6月5日上午10:12:10
	 * @param param
	 * @return
	 */
	public Map<String, Object> offlineRecharge(Map<String, Object> param){
		log.info("线下充值调用   请求参数：{}",param);
		Map<String, Object> respMap = new HashMap<String, Object>();
		String intoMobile = (String) param.get("intoMobile");
		String platformId = (String) param.get("platformId");
		String type = (String) param.get("type");
		String accType = (String) param.get("accType");
		String transferAmtStr = (String) param.get("transferAmt");
		BigDecimal transferAmt = new BigDecimal(transferAmtStr);
		String orderNo = (String) param.get("orderNo");
		String orderType = (String) param.get("orderType");

		Customer customer = null;
		if ("00".equals(type)) {
			customer = customerMapper.queryUserinfoByMobile(intoMobile,platformId);
			log.info("转入企业账户查询用户基础信息   请求参数：{}",EntityUtils.beanToMap(customer));
		}else{
			Customer customerReq = new Customer();
			customerReq.setPlatformId(platformId);
			customerReq.setCustomerType("00"); // 平台
			customer = customerMapper.selectOne(customerReq);
			log.info("转入平台账户查询用户基础信息   请求参数：{}",EntityUtils.beanToMap(customer));
		}
		if (null != customer) {
			if (null != customer.getMerId()) {
				Map<String, Object> reqMap = new HashMap<String, Object>();
				reqMap.put("merId", customer.getMerId());
				reqMap.put("platformId", platformId);
				reqMap.put("accType", accType);
				reqMap.put("orderNo", orderNo);
				reqMap.put("orderType", orderType);
				reqMap.put("transferAmt", transferAmtStr);
				respMap = deposit(param);
				
			} else {
				respMap.put("code", ResponseCode.MER_NOTEXIST.getCode());
				respMap.put("msg", ResponseCode.MER_NOTEXIST.getMessage());
			}
		
		} else {
			respMap.put("code", ResponseCode.CUST_NOTEXIST.getCode());
			respMap.put("msg", ResponseCode.CUST_NOTEXIST.getMessage());
		}
			
		log.info("线下充值调用   响应参数：{}",respMap);
		return respMap;
	}
	
	
	
	/**
	 * 查询商户账户
	 * @param map
	 * @return
	 */
	public List<MerchantAccountInfo> queryMerchantAccount(Map<String, Object> map) {
		log.info("查询商户账户参数。。。{}"+map);
		List<MerchantAccountInfo> list = merchantAccountMapper.queryMerchantAccountInfos(map);
		log.info("查询商户账户。。。{}"+list);
		return list;
	}
	
	
	/**
	 * 修改账户状态
	 * @param map
	 * @return
	 */
	public Map<String, Object> updateMerchantAccount(Map<String, Object> map) {
		log.info("修改账户状态参数。。。{}"+map);
		Map<String, Object> respMap = new HashMap<>();
		merchantAccountMapper.updateAccountStatus(map);
		respMap.put("code", ResponseCode.OK.getCode());
		respMap.put("msg", ResponseCode.OK.getMessage());
		return respMap;
	}

	/**
	 * 查询商户账户信息
	 * @author centerroot
	 * @time 创建时间:2018年6月4日上午11:49:39
	 * @param map
	 * @return
	 */
	public Map<String, Object> queryMerchantAccountInfo(Map<String, Object> map) {
		log.info("查询商户账户信息。。。请求参数：{}",map);
		Map<String, Object> respMap = new HashMap<>();
		MerchantAccount merchantAccountReq = new MerchantAccount();
		merchantAccountReq.setMerId((String) map.get("merId"));
		merchantAccountReq.setAccType(AccountType.ACC_BALANCE.getCode());
		MerchantAccount merAccBalResp = merchantAccountMapper.selectOne(merchantAccountReq);
		if (null != merAccBalResp && null != merAccBalResp.getAccBalance()) {
			log.info("根据商户编号查询商户余额账户信息结果：{}",merAccBalResp.toString());
			respMap.put("accountBalance", merAccBalResp.getAccBalance().toString());
		} else {
			respMap.put("accountBalance", "0");
		}
		
		merchantAccountReq.setAccType(AccountType.ACC_FREEZE.getCode());
		MerchantAccount merAccFreezeResp = merchantAccountMapper.selectOne(merchantAccountReq);
		if (null != merAccFreezeResp && null != merAccFreezeResp.getAccBalance()) {
			log.info("根据商户编号查询商户余额冻结账户信息结果：{}",merAccFreezeResp.toString());
			respMap.put("accountFreeze", merAccFreezeResp.getAccBalance().toString());
		} else {
			respMap.put("accountFreeze", "0");
		}
		
		respMap.put("code", ResponseCode.OK.getCode());
		respMap.put("msg", ResponseCode.OK.getMessage());
		log.info("查询商户账户信息。。。响应参数：{}",respMap);
		return respMap;
	}

	
}